package org.jeecg.modules.demo.pointcount.redis.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import jdk.nashorn.internal.objects.annotations.Where;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.demo.moenydata.entity.Moneydatahappycafe;
import org.jeecg.modules.demo.moenydata.uitils.GamesEnum;
import org.jeecg.modules.demo.moenydata.uitils.TimeUtil;
import org.jeecg.modules.demo.pointcount.entity.*;
import org.jeecg.modules.demo.pointcount.redis.entity.AsyncTaskData;
import org.jeecg.modules.demo.pointcount.redis.thread.AsyncTaskManager;
import org.jeecg.modules.demo.pointcount.redis.util.Config;
import org.jeecg.modules.demo.pointcount.service.IEventDataService;
import org.jeecg.modules.demo.userexist.entity.UserExistCountData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author yw
 * @Date 2021/3/12 17:31
 * 发送和存储任务消息
 */
@Component
@Slf4j
public class SendAndStorageProcess {
    @Autowired
    private RedisTemplate<String, AsyncTaskData> redisTemplate;
    @Autowired
    private AsyncTaskManager asyncTaskManage;

    /**
     * 从redis消费信息
     * @param message 对应redis中队列名
     * @return
     */
    public String getMessage(String message,int id) {
        String str="";
        try{
            //TODO 这里写一些发消息的业务逻辑
                long time=0;
                int num=0;
                List<AsyncTaskData> list=new ArrayList<>();
                log.info("获取Redis队列开始,队列名:"+message);
                while (num<5000) {
                    Object strJson=redisTemplate.opsForList().rightPop(message,100, TimeUnit.MILLISECONDS);
                    if(strJson!=null){
                         str = JSONObject.toJSONString(strJson);
                        if(str.indexOf("[")==0){ //当【 为0说明格式不正确，要进行分割
                            List strList= JSON.parseArray(str);
                            str=JSONObject.toJSONString(strList.get(1));
                        }

                    AsyncTaskData data=new AsyncTaskData();
                            switch (id){
                                case 1:
                                    CheckData checkData=JSONObject.parseObject( str,CheckData.class);
                                    data.setData(checkData);
                                    data.setCmd("checkData");
                                    break;
                                case 2:
                                    OnlineData onlineData=JSONObject.parseObject( str,OnlineData.class);
                                    data.setData(onlineData);
                                    data.setCmd("onlineDataAdd");
                                    break;
                                case 3:
                                    SpecialEventData specialEventData=JSONArray.parseObject( str,SpecialEventData.class);
                                    data.setData(specialEventData);
                                    data.setCmd("specialEventData");
                                    break;
                                case 4:
                                    EventData eventData = JSON.parseObject( str,EventData.class);
                                    data.setData(eventData);
                                    data.setCmd("eventData");
                                    break;
                                case 5:
                                    Moneydatahappycafe moneydatahappycafe = JSON.parseObject( str,Moneydatahappycafe.class);
                                    data.setData(moneydatahappycafe);
                                    data.setCmd("moneyData");
                                    break;
                                case 6:
                                    OnlineData online=JSONObject.parseObject( str,OnlineData.class);
                                    data.setData(online);
                                    data.setCmd("onlineDataUpdate");
                                    break;
                                default:
                                    log.info("发生异常！");
                                    break;
                            }
                            list.add(data);

                            //log.info(Thread.currentThread().getName() + "线程执行成功，用户id为：" + msg.getUserid() + "执行到第-" + (num + 1) + "-条");
                            num++;
                        }else{
                            break;
                        }
                    }


                log.info("获取队列成功,list长度："+list.size());
                if(list.size()!=0){
                        storageMessage(list);


                }

            //Thread.sleep(2000);     //增加耗时操作，查看多线程效果
           // System.out.println(Thread.currentThread().getName() + "线程发送消息成功，消息内容：" + message.getContent());
            return "200";   //发送消息结果状态码
        } catch (Exception e) {
            System.out.println(id+"抱錯日志"+str );
            e.printStackTrace();
        }
        return "500";   //发送消息结果状态码
    }

    /*
     * 定时消费online玩家数据
     */
    public void getOnlineMessage(String num){
        log.info("进入消费");
        try {
        String listTime= TimeUtil.getPreTime("");//获取前一天的日期
        String time=TimeUtil.getNowTimestamp();
        String begDataName=GamesEnum.getTableName(num);//表名前缀
        String dataName= begDataName+"onlinedata";
        String dataNameForUserExist=begDataName+"userexist";

        int totalPlayerNum=0;//玩家总数
        Double timePlayerCount=0.0;//时长总数
        List<AsyncTaskData> dataList=new ArrayList<>();//在线用户数据list
        List<AsyncTaskData> dataListForChannelList=new ArrayList<>();//在线用户-统计数据list
        List<AsyncTaskData> dataListForUserExistList=new ArrayList<>();//用户留存-统计数据list
        //List<OnlineReturnData> countList=new ArrayList<>();

        UserExistCountData userExistCountDataForAll=new UserExistCountData();
        userExistCountDataForAll.setId(null);
        userExistCountDataForAll.setTableName(dataNameForUserExist);
        userExistCountDataForAll.setCtime(time);
        userExistCountDataForAll.setChannelName("all");
        AsyncTaskData asyncTaskDataForUserExist=new AsyncTaskData();
        asyncTaskDataForUserExist.setCmd(Config.TASK_ADD_USEREXISTCOUNTDATA);
        //获取渠道队列
        String channelListName="Player_"+listTime+"_"+num+"_channel";
        while (true){
            Object channelStr=redisTemplate.opsForList().rightPop(channelListName,100, TimeUnit.MILLISECONDS);
            if(channelStr==null){
                break;
            }
            AsyncTaskData dataForChannel=new AsyncTaskData();
            OnlineData countData=new OnlineData();
            countData.setTableName(dataName+"count");
            countData.setId(null);
            dataForChannel.setCmd(Config.TASK_ADDONLINEDATACOUNT);
            int totalNumForChannel=0;
            Double timeCountForChannel=0.0;

            //获取渠道名称
            String channelName=String.valueOf(channelStr);
            String listName="Player_"+listTime+"_"+num+"_"+channelName;//用户userid队列

            UserExistCountData userExistCountDataForChannel=new UserExistCountData();
            userExistCountDataForChannel.setId(null);
            userExistCountDataForChannel.setChannelName(channelName);
            userExistCountDataForChannel.setTableName(dataNameForUserExist);
            userExistCountDataForChannel.setCtime(time);
            AsyncTaskData asyncTaskDataForUser=new AsyncTaskData();
            asyncTaskDataForUser.setCmd(Config.TASK_ADD_USEREXISTCOUNTDATA);

             while (true){
                    Object strJson=redisTemplate.opsForList().rightPop(listName,100, TimeUnit.MILLISECONDS);
                    if(strJson==null){
                         break;
                    }
                            String userId=String.valueOf(strJson);
                            //获取用户
                            String userListName=listName+"_"+userId;
                            Object listJson=redisTemplate.opsForValue().get(userListName);
                            if(listJson==null){
                                break;
                            }
                            String jsonData=JSONObject.toJSONString(listJson);
                            if(jsonData.indexOf("[")==0){ //当【 为0说明格式不正确，要进行分割
                                List strList= JSON.parseArray(jsonData);
                                jsonData=JSONObject.toJSONString(strList.get(1));
                            }
                            OnlineData onlineData=new OnlineData();
                            onlineData=JSONObject.parseObject( jsonData,OnlineData.class);
                            onlineData.setTableName(dataName);
                            Double dataTimeCount=onlineData.getDuration();
                            String timeStamp1=onlineData.getRegTime();//注册时间
                            String timeStamp2=onlineData.getTime();//最后登录时间

                    Double diffDay=TimeUtil.getStampDIFF(timeStamp1,timeStamp2);
                    userExistCountDataForChannel.setDay(diffDay);

                    userExistCountDataForAll.setDay(diffDay);

                    timeCountForChannel+=dataTimeCount;
                    AsyncTaskData asyncTaskData=new AsyncTaskData();
                    asyncTaskData.setData(onlineData);
                    asyncTaskData.setCmd("onlineDataAdd");
                    dataList.add(asyncTaskData);
                    totalNumForChannel++;
            }
            asyncTaskDataForUser.setData(userExistCountDataForChannel);
            dataListForUserExistList.add(asyncTaskDataForUser);


            totalPlayerNum+=totalNumForChannel;
            timePlayerCount+=timeCountForChannel;
            Double avgForChannel=totalNumForChannel/timeCountForChannel;
            countData.setPlayerCount(totalNumForChannel);
            countData.setTimeCount(timeCountForChannel);
            countData.setTime(time);
            countData.setTimeAvg(avgForChannel);
            countData.setChannelName(channelName);
            dataForChannel.setData(countData);
            dataListForChannelList.add(dataForChannel);
        }
        //所有玩家数据
        if(totalPlayerNum!=0){
            AsyncTaskData dataForChannelAll=new AsyncTaskData();
            dataForChannelAll.setCmd("onlineDataForChanel");
            Double avg=timePlayerCount/totalPlayerNum;
            OnlineData allPlayerData=new OnlineData();
            allPlayerData.setId(null);
            allPlayerData.setTime(time);
            allPlayerData.setPlayerCount(totalPlayerNum);
            allPlayerData.setTimeCount(timePlayerCount);
            allPlayerData.setTimeAvg(avg);
            allPlayerData.setChannelName("0");
            allPlayerData.setTableName(dataName+"count");
            dataForChannelAll.setData(allPlayerData);
            dataListForChannelList.add(dataForChannelAll);

            //插入用户留存统计数据
            asyncTaskDataForUserExist.setData(userExistCountDataForAll);
            dataListForUserExistList.add(asyncTaskDataForUserExist);
            storageMessage(dataListForUserExistList);

            storageMessage(dataListForChannelList);
            storageMessage(dataList);
        }
        }catch (Exception e){
            e.printStackTrace();
        }
    }



    /**
     * 存消息到数据库
     * @param list
     * @return
     */
    private void storageMessage(List<AsyncTaskData> list) {
        try{
            log.info("开始对数据进行持久化");
            for (int i=0;i<list.size();i++){
                asyncTaskManage.addTask(list.get(i));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        log.info("数据持久化结束");
    }


}
